package com.dream.app.controller;

import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.dream.app.cache.AppCodeCache;
import com.dream.app.service.OrgService;
import com.dream.base.controller.BaseController;
import com.dream.master.service.ShopService;
import com.dream.model.stock.ProductPartRequest;
import com.dream.model.stock.ProductPartRequest.RequestStatus;
import com.dream.model.stock.ProductPartRequest.StockDirection;
import com.dream.model.stock.ProductPartStock;
import com.dream.model.stock.ProductPartStock.StockProductType;
import com.dream.model.stock.StockExpress;
import com.dream.stock.service.StockService;
import com.dream.utils.annotation.AccessLog;
import com.dream.utils.annotation.SkipAuthority;
import com.dream.utils.hibernate.PagingVO;
import com.dream.utils.log.DreamLogUtils;
import com.dream.vo.app.AppCodeConstants;
import com.dream.vo.base.FirstGroup;
import com.dream.vo.base.MvcValidtorResult;
import com.dream.vo.base.ResultType;
import com.dream.vo.stock.PartRequestVO;
import com.dream.vo.stock.ProductPartStockVO;
import com.dream.vo.stock.StockExpressVO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * @copyright evan
 * @author evan
 * @Revision
 * @date 2013/9/29
 */
@Controller
@RequestMapping(value = "/stock")
public class StockController extends BaseController{
	
	@Autowired
	private AppCodeCache appCodeCache;
	
	@Autowired
	private StockService stockService;
	
	@Autowired
	private ShopService shopService;
	
	@Autowired
	private OrgService orgService;
	
	@RequestMapping(value = "/list/init")
	@SkipAuthority
	public String stockListInit(Model modelMap,String loc) {
		
		modelMap.addAttribute("stockProductTypes", StockProductType.getTypes());
		modelMap.addAttribute("firstOrgs",orgService.getFirstOrgOfMine(this.getUser()));
		return loc;
		
	}
	
	@RequestMapping(value = "/list")
	@SkipAuthority
	public String stockList(Model modelMap,ProductPartStockVO vo,PagingVO page) {
		
		modelMap.addAttribute("pageVO", stockService.queryAllStock(vo, page,getUser()));
		return "stock/data/stock_list_data";
		
	}
	
	@RequestMapping(value = "/mine/list/init")
	@SkipAuthority
	public String stockMineListInit(Model modelMap) {
		
		modelMap.addAttribute("stockProductTypes", StockProductType.getTypes());
		modelMap.addAttribute("shops", shopService.queryMyShop(getUser()));
		return "stock_mine_list";
		
	}
	
	@RequestMapping(value = "/mine/list")
	@SkipAuthority
	public String stockMineList(Model modelMap,ProductPartStockVO vo,PagingVO page) {
		
		modelMap.addAttribute("pageVO", stockService.queryMyStock(vo, page,getUser()));
		return "stock/data/stock_mine_list_data";
		
	}
	
	@RequestMapping(value = "/mine/update/{id}/{number}")
	@SkipAuthority
	@ResponseBody
	public Map<String, Object> stockMineUpate(Model modelMap,@PathVariable String id, @PathVariable Integer number) {
		
		Map<String, Object> result = Maps.newHashMap();	
		try{
			stockService.updateStock(id, number, getUser());
			result.put(RESULT_TYPE,ResultType.SUCCESS.toInteger());
		}catch(Exception ex){
				result.put(RESULT_TYPE, ResultType.EXCEPTION.toInteger());
				DreamLogUtils.error(this,"stockRequestSubmit","submit stock occured exception", ex);
		}
			
		return result;
		
	}
	
	
	@RequestMapping(value = "/in/request/init")
	@SkipAuthority
	public String stockInRequestInit(Model modelMap) {
		
		modelMap.addAttribute("stockProductTypes", StockProductType.getTypes());
		modelMap.addAttribute("shops", shopService.queryMyShop(getUser()));
		return "stock_in_request";
		
	}
	
	@RequestMapping(value = "/out/request/init")
	@SkipAuthority
	public String stockOutRequestInit(Model modelMap) {
		
		modelMap.addAttribute("stockProductTypes", StockProductType.getTypes());
		modelMap.addAttribute("shops", shopService.queryMyShop(getUser()));
		return "stock_out_request";
		
	}
	
	@RequestMapping(value = "/request/submit")
	@SkipAuthority
	@ResponseBody
	public Map<String, Object> stockRequestSubmit(Model modelMap,ProductPartStockVO vo) {
		
		Map<String, Object> result = Maps.newHashMap();	
		try{
			stockService.submitInStock(vo, getUser());
			result.put(RESULT_TYPE,ResultType.SUCCESS.toInteger());
		}catch(Exception ex){
				result.put(RESULT_TYPE, ResultType.EXCEPTION.toInteger());
				DreamLogUtils.error(this,"stockRequestSubmit","submit stock occured exception", ex);
		}
			
		return result;
		
	}
	
	@RequestMapping(value = "/search/item")
	@SkipAuthority
	@AccessLog(module="master",content="配件库存查询")
	public String productPartSearch(Model modelMap,ProductPartStockVO vo) {
		
		List<ProductPartStock> stocks = stockService.searchProductPart(vo);
		modelMap.addAttribute("stocks", stocks);
		modelMap.addAttribute("isEmpty", CollectionUtils.isEmpty(stocks));
		return "stock/data/stock_search_data";
		
	}
	
	@RequestMapping(value = "/app/list")
	@SkipAuthority
	public String stockApproveList(Model modelMap,ProductPartStockVO vo,PagingVO page) {
		
		List<RequestStatus> status = Lists.newArrayList(RequestStatus.submit);
		vo.setStatus(status);
		PagingVO pagingVO = stockService.queryRequest(vo, page,this.getUser());
		modelMap.addAttribute("pageVO", pagingVO);
		return "stock/data/stock_app_list_data";
		
	}
	
	@RequestMapping(value = "/post/list")
	@SkipAuthority
	public String stockPostList(Model modelMap,ProductPartStockVO vo,PagingVO page) {
		
		List<RequestStatus> status = Lists.newArrayList(RequestStatus.approve);
		vo.setStatus(status);
		PagingVO pagingVO = stockService.queryRequest(vo, page,this.getUser());
		modelMap.addAttribute("pageVO", pagingVO);
		modelMap.addAttribute("expressTypes", appCodeCache.getByAppCodeName(AppCodeConstants.EXPRESS_TYPE));
		return "stock/data/stock_post_list_data";
		
	}
	
	@RequestMapping(value = "/post/update")
	@SkipAuthority
	@ResponseBody
	public Map<String,Object> postUpdate(Model modelMap,@Validated({FirstGroup.class}) StockExpressVO vo,BindingResult valResult) {
		
		
		Map<String,Object> result = Maps.newHashMap();
		MvcValidtorResult errors = populateErrors(valResult);
		
		if(valResult.hasErrors()){
			result.put(RESULT_TYPE, ResultType.INPUT.toInteger());
			result.put(RESULT_CONTENT, errors);
			
		}else{
			try{
					stockService.updatePost(vo, getUser());
					result.put(RESULT_TYPE,ResultType.SUCCESS.toInteger());
					
			}catch(Exception ex){
					result.put(RESULT_TYPE, ResultType.EXCEPTION.toInteger());
					DreamLogUtils.error(this,"postUpdate","update post  occured exception", ex);
			}
		}
		return result;
		
		
	}
	
	@RequestMapping(value = "/post/detail/{id}")
	@SkipAuthority
	public String postDetail(Model modelMap,@PathVariable Long id) {
		
		modelMap.addAttribute("expressTypes", appCodeCache.getByAppCodeName(AppCodeConstants.EXPRESS_TYPE));
		modelMap.addAttribute("display", true);
		modelMap.addAttribute("vo", stockService.getExpress(id));
		return "stock_post_update";
	}
	
	@RequestMapping(value = "/post/update/init/{id}")
	@SkipAuthority
	public String postUpdateInit(Model modelMap,@PathVariable Long id) {
		
		modelMap.addAttribute("expressTypes", appCodeCache.getByAppCodeName(AppCodeConstants.EXPRESS_TYPE));
		modelMap.addAttribute("stockRequestId", id);
		modelMap.addAttribute("display", false);
		ProductPartRequest request = stockService.getRequest(id);
		if(request != null){
			
			StockExpress vo = new StockExpress();
			if(StockDirection.in.equals(request.getRequestType())){
				vo.setFromAddress(request.getFromShop().getAddress());
				vo.setFromName(request.getFromShop().getName());
				vo.setFromContact(request.getFromShop().getContact());
				vo.setFromUser(request.getFromShop().getShopPic());
				
				vo.setToAddress(request.getToShop().getAddress());
				vo.setToName(request.getToShop().getName());
				vo.setToContact(request.getToShop().getContact());
				vo.setToUser(request.getToShop().getShopPic());
			}
			if(StockDirection.out.equals(request.getRequestType())){
				vo.setToAddress(request.getFromShop().getAddress());
				vo.setToName(request.getFromShop().getName());
				vo.setToContact(request.getFromShop().getContact());
				vo.setToUser(request.getFromShop().getShopPic());
				
				vo.setFromAddress(request.getToShop().getAddress());
				vo.setFromName(request.getToShop().getName());
				vo.setFromContact(request.getToShop().getContact());
				vo.setFromUser(request.getToShop().getShopPic());
			}
			
			
			modelMap.addAttribute("vo", vo);
			
		}
		return "stock_post_update";
		
	}
	
	@RequestMapping(value = "/rcv/list")
	@SkipAuthority
	public String stockReceiveList(Model modelMap,ProductPartStockVO vo,PagingVO page) {
		

		List<RequestStatus> status = Lists.newArrayList(RequestStatus.post);
		vo.setStatus(status);
		PagingVO pagingVO = stockService.queryRequest(vo, page,this.getUser());
		modelMap.addAttribute("pageVO", pagingVO);
		modelMap.addAttribute("unnormalTypes", appCodeCache.getByAppCodeName(AppCodeConstants.RCV_UNNORMAL_TYPE));
		return "stock/data/stock_rcv_list_data";
		
		
	}
	
	@RequestMapping(value = "/history/list")
	@SkipAuthority
	public String stockHistoryList(Model modelMap,ProductPartStockVO vo,PagingVO page) {
		
		List<RequestStatus> status = Lists.newArrayList(RequestStatus.reject,RequestStatus.received,RequestStatus.other);
		vo.setStatus(status);
		PagingVO pagingVO = stockService.queryReqHistory(vo, page,this.getUser());
		modelMap.addAttribute("pageVO", pagingVO);
		return "stock/data/stock_history_list_data";
		
	}
	
	@RequestMapping(value = "/app/action/{type}")
	@SkipAuthority
	@ResponseBody
	public Map<String, Object> stockApproveAction(Model modelMap,@PathVariable String type,PartRequestVO vo) {
		
		Map<String, Object> result = Maps.newHashMap();	
		try{
			stockService.doActionRequest(type, vo, getUser());
			result.put(RESULT_TYPE,ResultType.SUCCESS.toInteger());
		}catch(Exception ex){
				result.put(RESULT_TYPE, ResultType.EXCEPTION.toInteger());
				DreamLogUtils.error(this,"stockApproveAction","approve stock occured exception", ex);
		}
			
		return result;
	}
	
	
}
